Required field messages
In our contact form, required fields have class="required" to allow for styling as well as response to user input; the input fields for each type of contact have class="conditional"
applied to them. We're going to use these classes to change the
instructions printed within parentheses to the right of each input.
We start by setting variables for requiredFlag and conditionalFlag, and then we fill the<span> element next to each required and conditional field with the text stored in those variables:
$(document).ready(function() {
var requiredFlag = ' * ';
var conditionalFlag = ' ** ';
$('form :input')
.filter('.required')
.next('span').text(requiredFlag).end()
.end()
.filter('.conditional')
.next('span').text(conditionalFlag);
});
Using .end() allows
us to extend the chain of methods so that we continue to work with the
same set of elements and keep object creation and DOM traversal to a
minimum. Each .end() method takes the
selection back one step, reverting the matched set of elements to what
it was before the last traversal method. Here we use two in a row: the
first .end() reverts the matched set to .filter('.required') and the second reverts it to $('form :input'). Thus, when .filter('.conditional') selects elements with class="conditional", it applies to all inputs within the form.
Now, since a single asterisk (*) may not immediately capture the user's attention, we'll also add class="req-label" to the<label> for each required field and apply font-weight:bold to that class. To do so, we can extend the chain even further.
$(document).ready(function() {
var requiredFlag = ' * ';
var conditionalFlag = ' ** ';
$('form :input')
.filter('.required')
.next('span').text(requiredFlag).end()
.prev('label').addClass('req-label').end()
.end()
.filter('.conditional')
.next('span').text(conditionalFlag);
});
Such a long chain of methods can be difficult to follow, so a consistent line-break and indentation pattern is essential.
The fieldset with the modified text and the added class now looks like this:
Not bad. Still, the
required and conditional field messages really weren't so bad after
all; they were just too repetitive. Let's take the first instance of
each message and display it above the form next to the flag we're using
to symbolize it.
Before we populate the<span>
elements holding the messages with their respective flags, we need to
store the initial messages in a couple of variables. Then we can strip
out the parentheses by using a regular expression:
$(document).ready(function() {
var requiredFlag = ' * ';
var conditionalFlag = ' ** ';
var requiredKey = $('input.required:first')
.next('span').text();
var conditionalKey = $('input.conditional:first')
.next('span').text();
requiredKey = requiredFlag +
requiredKey.replace(/^\((.+)\)$/,'$1');
conditionalKey = conditionalFlag +
conditionalKey.replace(/^\((.+)\)$/,'$1');
// . . . code continues
});
The first two additional lines declare variables—requiredKey and conditionalKey—to
store each field type's text. The second two lines modify the text in
those variables, concatenating each flag, and its respective text,
minus the parentheses. Perhaps the regular expression, along with its .replace() method, warrants further explanation.